package com.ihr360.payroll.model.dto.salary.task.period;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ihr360.commons.model.meta.table.DynamicCell;
import com.ihr360.hibernate.type.encrypt.JsonEncryptType;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalarySnapshot;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalarySnapshotListWrapper;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalaryTermId;
import com.ihr360.payroll.type.StaffRefStatus;
import com.ihr360.shared.entitywithlistener.TimeEntity;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Entity
@TypeDefs({
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        @TypeDef(name = "json-encrypt", typeClass = JsonEncryptType.class)
})

/**
 * 一个员工在一个账期批次内只能有一条记录
 */

@Table(
        indexes = {@Index(name = "company_staff_index", columnList = "companyId,staffId,year,month")})
//@IdClass(StaffSalaryTermId.class)
@DynamicUpdate
public class StaffPayPeriodTermSalary extends TimeEntity implements Serializable {

    private static final long serialVersionUID = -3374062253666057557L;

    public static final class Field {
        public static final String ATTENDANCE_STATUS = "attendanceStatus";
        public static final String SIHF_STATUS = "sihfStatus";
    }


    @EmbeddedId
    StaffSalaryTermId id;

    @Column(length = 40, nullable = false, name = "companyId")
    private String companyId;

    @Column(length = 32, nullable = true, name = "staffName")
    private String staffName;

    @Column(length = 18, nullable = true, name = "mobileNo")
    private String mobileNo;

    @Column(length = 40, nullable = true, name = "departmentName")
    private String departmentName;

    @Column(nullable = true, name = "departmentId")
    private Long departmentId;

    private int year;
    private int month;
    /**
     * 计算开始日期
     */
    @Column(nullable = false, columnDefinition = "date")
    private Date startOn;
    /**
     * 计算结束日期
     */
    @Column(nullable = false, columnDefinition = "date")
    private Date endOn;
    /**
     * 批次
     */
    @MapsId("term_id")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(nullable = false, name = "term_id")
    private PayPeriodTerm term;

    @Column(columnDefinition = "text")
    @Type(type = "json-encrypt")
    private StaffSalarySnapshot summarizedData;

    @Column(columnDefinition = "text")
    @Type(type = "json-encrypt")
    private StaffSalarySnapshotListWrapper phasedData;

    /**
     * 社保状态
     */
    @Enumerated(EnumType.STRING)
    @Column(length = 10)
    private StaffRefStatus sihfStatus;
    /**
     * 考勤状态
     */
    @Column(length = 10)
    @Enumerated(EnumType.STRING)
    private StaffRefStatus attendanceStatus;

    @JsonIgnore
    public Map<String, Object> getSalaryDynamicCell() {
        Map<String, DynamicCell> dynamicCellMap = summarizedData.getData();
        if (dynamicCellMap == null || dynamicCellMap.size() <= 0) {
            return new HashMap<>(0);
        }
        Map<String, Object> result = new HashMap<>(dynamicCellMap.size());
        dynamicCellMap.forEach((key, value) -> result.put(key, value.getCellValue()));
        return result;
    }

    public String getStaffId() {
        return this.id.getStaffId();
    }

    public String getStaffName() {
        return staffName;
    }

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public Long getDepartmentId() {
        return departmentId;
    }

    public void setDepartmentId(Long departmentId) {
        this.departmentId = departmentId;
    }

    public void setStaffName(String staffName) {
        this.staffName = staffName;
    }

    public String getMobileNo() {
        return mobileNo;
    }

    public void setMobileNo(String mobileNo) {
        this.mobileNo = mobileNo;
    }

    public StaffSalaryTermId getId() {
        return id;
    }

    public void setId(StaffSalaryTermId id) {
        this.id = id;
    }

    public String getCompanyId() {
        return companyId;
    }

    public void setCompanyId(String companyId) {
        this.companyId = companyId;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public Date getStartOn() {
        return startOn;
    }

    public void setStartOn(Date startOn) {
        this.startOn = startOn;
    }

    public Date getEndOn() {
        return endOn;
    }

    public void setEndOn(Date endOn) {
        this.endOn = endOn;
    }

    public PayPeriodTerm getTerm() {
        return term;
    }

    public void setTerm(PayPeriodTerm term) {
        this.term = term;
    }

    public StaffSalarySnapshot getSummarizedData() {
        return summarizedData;
    }

    public void setSummarizedData(StaffSalarySnapshot summarizedData) {
        this.summarizedData = summarizedData;
    }

    public StaffSalarySnapshotListWrapper getPhasedData() {
        return phasedData;
    }

    public void setPhasedData(StaffSalarySnapshotListWrapper phasedData) {
        this.phasedData = phasedData;
    }

    public StaffRefStatus getSihfStatus() {
        return sihfStatus;
    }

    public void setSihfStatus(StaffRefStatus sihfStatus) {
        this.sihfStatus = sihfStatus;
    }

    public StaffRefStatus getAttendanceStatus() {
        return attendanceStatus;
    }

    public void setAttendanceStatus(StaffRefStatus attendanceStatus) {
        this.attendanceStatus = attendanceStatus;
    }
}
